import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URLDecoder;

import javax.swing.BoxLayout;
import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class JImageViewer extends JApplet  implements KeyListener, MouseListener {
    
	private int mode=0;
	private String param_urls;
	private Image image=null;
	private MediaTracker mediatracker=null;
	
	private String[] urls;
	private int position =0;
	
	private Dimension area;
	private final int GAP=3;
	
	public void init() {
		
		addKeyListener(this);
		setFocusable(true);
		
		param_urls=getParameter("param_urls");
		urls = param_urls.split("]");
		for(int i=0;i<urls.length;i++){
			try{
				urls[i] = URLDecoder.decode(urls[i],"UTF-8");
			}catch(Exception e){
				
			}
		}
		
		area = new Dimension(getJAppletWidth()-GAP,getJAppletHeight()-GAP);
		loadImage();
		
		try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    createGUI();
                }
            });
        } catch (Exception e) {
            System.err.println("createGUI didn't successfully complete");
        }
    }
	
	public void loadImage(){
		mediatracker = new MediaTracker(this);
		image = getImage(getDocumentBase(),urls[position]);
		
		mediatracker.addImage(image, 0);
		
		try
		{
			mediatracker.waitForAll();
		}
		catch (Exception e)	{};
	}
	
    private void createGUI() {
    	ScrollPane newContentPane = new ScrollPane();
        newContentPane.setOpaque(true); //content panes must be opaque
        
        setContentPane(newContentPane);
    }
    
    private int getJAppletX(){
    	return getX();
    }
    
    private int getJAppletY(){
    	return getY();
    }
    private int getJAppletWidth(){
    	return getWidth();
    }
    
    private int getJAppletHeight(){
    	return getHeight();
    }
    
    //sub class
    private class ScrollPane extends JPanel{
    	
    	private DrawingPane drawingPane;
        
        public ScrollPane() {
            super(new BorderLayout());
            
            //Set up the drawing area.
            drawingPane = new DrawingPane();
            drawingPane.setBackground(Color.black);
            
            drawingPane.setPreferredSize(area);
            //Put the drawing area in a scroll pane.
            JScrollPane scroller = new JScrollPane(drawingPane);
            //scroller.setPreferredSize(new Dimension(200,200));

            //Lay out this demo.
            add(scroller, BorderLayout.CENTER);
            
            
        }
        
        public void repaintPicture(){
        	drawingPane.updatePreferredSize();
        	drawingPane.revalidate();
        	drawingPane.repaint();
        }
        
    }
    
    
    /** The component inside the scroll pane. */
    public class DrawingPane extends JPanel {
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
        	Graphics2D g2 = (Graphics2D)g;
    		
    		int width = getJAppletWidth();
    		int height = getJAppletHeight();
    		
    		int image_width = image.getWidth(null);
    		int image_height = image.getHeight(null);
    		
    		double rate;
    		
    		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, // Anti-alias!
    		        RenderingHints.VALUE_INTERPOLATION_BICUBIC);
    		switch(mode){
    		case 0:
    			if(image_width>width || image_height>height){
    				if(height>width){
    					if((double)image_width/(double)image_height <(double)width/(double)height){
    						rate=(double)image_width/(double)image_height;
    						g2.drawImage(image,(int)(width-(height*rate))/2,0,(int)(height*rate),height,null);
    					}else{
    						rate=(double)image_height/(double)image_width;
    						g2.drawImage(image,0,(int)(height-(width*rate))/2,width,(int)(width*rate),null);
    					}
    				}else{
    					if((double)image_height/(double)image_width <(double)height/(double)width){
    						rate=(double)image_height/(double)image_width;
    	 					g2.drawImage(image,0,(int)(height-(width*rate))/2,width,(int)(width*rate),null);
    					}else{
    						rate=(double)image_width/(double)image_height;
    						g2.drawImage(image,(int)(width-(height*rate))/2,0,(int)(height*rate),height,null);
    					}
    				}
    			}else{
    				//center
    				g2.drawImage(image, (width/2)-(image_width/2), (height/2)-(image_height/2), null);
    			}
    			area.width=0;
				area.height=0;
				break;
    		case 1:
    			width-=15;
    			if(height>width){
					if((double)image_width/(double)image_height <(double)width/(double)height){
						rate=(double)image_height/(double)image_width;
						g2.drawImage(image,0,0,width,(int)(width*rate),null);
					}else{
						width+=15;
						rate=(double)image_height/(double)image_width;
						g2.drawImage(image,0,(int)(height-(width*rate))/2,width,(int)(width*rate),null);
					}
				}else{
					if((double)image_height/(double)image_width <(double)height/(double)width){
						width+=15;
						rate=(double)image_height/(double)image_width;
	 					g2.drawImage(image,0,(int)(height-(width*rate))/2,width,(int)(width*rate),null);
					}else{
						rate=(double)image_height/(double)image_width;
						g2.drawImage(image,0,0,width,(int)(width*rate),null);
					}
				}
    			area.width=width-GAP;
				area.height=(int)(width*rate)-GAP;
				break;
    		case 2:
    			height-=15;
    			if(height>width){
					if((double)image_width/(double)image_height <(double)width/(double)height){
						height+=15;
						rate=(double)image_width/(double)image_height;
						g2.drawImage(image,(int)(width-(height*rate))/2,0,(int)(height*rate),height,null);
					}else{
						rate=(double)image_width/(double)image_height;
						g2.drawImage(image,0,0,(int)(height*rate),height,null);
					}
				}else{
					if((double)image_height/(double)image_width <(double)height/(double)width){
						rate=(double)image_width/(double)image_height;
						g2.drawImage(image,0,0,(int)(height*rate),height,null);
					}else{
						height+=15;
						rate=(double)image_width/(double)image_height;
						g2.drawImage(image,(int)(width-(height*rate))/2,0,(int)(height*rate),height,null);
					}
				}
    			area.width=(int)(height*rate)-GAP;
				area.height=height-GAP;
				break;
    		case 3:
    			area.width=image_width;
				area.height=image_height;
				
    			if(image_width>width && image_height>height){
    				g2.drawImage(image,0,0,image_width,image_height,null);
    			}else if(image_width>width){
    				g2.drawImage(image,0,(int)(height-image_height)/2,image_width,image_height,null);
    			}else if(image_height>height){
    				g2.drawImage(image,(int)(width-image_width)/2,0,image_width,image_height,null);
    			}else{
    				//center
    				g2.drawImage(image, (width/2)-(image_width/2), (height/2)-(image_height/2), null);
    				area.width=0;
    				area.height=0;
    			}
    			
				break;
    		}
    		g=g2;
        }
        
        public void updatePreferredSize(){
        	int width = getJAppletWidth();
    		int height = getJAppletHeight();
    		
    		int image_width = image.getWidth(null);
    		int image_height = image.getHeight(null);
    		
    		double rate;
    		
    		switch(mode){
    		case 0:
    			area.width=0;
				area.height=0;
				break;
    		case 1:
    			width-=15;
    			if(height>width){
					if((double)image_width/(double)image_height <(double)width/(double)height){
						rate=(double)image_height/(double)image_width;
					}else{
						width+=15;
						rate=(double)image_height/(double)image_width;
					}
				}else{
					if((double)image_height/(double)image_width <(double)height/(double)width){
						width+=15;
						rate=(double)image_height/(double)image_width;
	 				}else{
						rate=(double)image_height/(double)image_width;
					}
				}
    			area.width=width-GAP-15;
				area.height=(int)(width*rate)-GAP;
				break;
    		case 2:
    			height-=15;
    			if(height>width){
					if((double)image_width/(double)image_height <(double)width/(double)height){
						height+=15;
						rate=(double)image_width/(double)image_height;
					}else{
						rate=(double)image_width/(double)image_height;
					}
				}else{
					if((double)image_height/(double)image_width <(double)height/(double)width){
						rate=(double)image_width/(double)image_height;
					}else{
						height+=15;
						rate=(double)image_width/(double)image_height;
					}
				}
    			area.width=(int)(height*rate)-GAP;
				area.height=height-GAP;
				break;
    		case 3:
    			area.width=image_width;
				area.height=image_height;
				if(image_width<=width && image_height<=height){
    				area.width=0;
    				area.height=0;
    			}
				
    			break;
    		}
    		setPreferredSize(area);
        }
    }
    
    private void previousPage()
    {
        --position;
        if (position < 0)
        {
        	position=urls.length - 1;
        }
        loadImage();
        repaintPicture();
    }

    private void nextPage()
    {
        ++position;
        if (position==urls.length)
        {
            position = 0;
        }
        loadImage();
        repaintPicture();
    }
    
    private void repaintPicture(){
    	ScrollPane scrollpane = (ScrollPane)getContentPane();
        scrollpane.repaintPicture();
        
    }
   
    private void jAppletrepaintPicture(){
    	loadImage();
    	repaintPicture();
    }
    
    
    public void keyPressed( KeyEvent e ) { }
    public void keyReleased( KeyEvent e ) { }
    public void keyTyped( KeyEvent e ) {
    	char c = e.getKeyChar();
       
		int int_c = (int)c;
       
		if(int_c==97 || int_c==65){
			//a || A
			if(mode!=0){
				mode=0;
				repaintPicture();
		   }
		}else if(int_c==119 || int_c==87){
			//w || W
			if(mode!=1){
				mode=1;
				repaintPicture();
			}
		}else if(int_c==104 || int_c==72){
			//h || H
			if(mode!=2){
				mode=2;
				repaintPicture();
			}
		}else if(int_c==111 || int_c==79){
		   //o || O
		   if(mode!=3){
			   mode=3;
			   repaintPicture();
		   }
		}else if(int_c==112 || int_c==80){
		   //p || P
		   new DLG(this).open();
		}else if(int_c==32){
			nextPage();
		}else if(int_c==8){
		   previousPage();
		}
		
    }
    
    public void mouseReleased(MouseEvent e) {
    	
    }
    public void mouseClicked(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mousePressed(MouseEvent e){}
    
    class DLG extends JDialog {
    	private JLabel jlabel = null;
    	private JTextField jtf = null;
    	private String result = "";

    	public DLG(JApplet parent) {
    		super(JOptionPane.getFrameForComponent(parent), true);

    		final JDialog dlg = this;

    		jlabel= new JLabel("1-"+urls.length);
    		jtf = new JTextField();
    		jtf.setText(String.valueOf(position+1));
    		jtf.addKeyListener(new KeyAdapter() {
		    	public void keyPressed(KeyEvent ke) {
			    		if(ke.getKeyCode() == 10) {
			    			result = jtf.getText();
			    			dlg.setVisible(false);
			    			if(0<Integer.parseInt(result) && Integer.parseInt(result)<=urls.length){
			    				position=Integer.parseInt(result)-1;
			    				jAppletrepaintPicture();
			    			}
			    		}
			    	}
		    	});
    	
    		getContentPane().add(jlabel, BorderLayout.PAGE_START);
    		getContentPane().add(jtf, BorderLayout.PAGE_END);
    			
    		//setSize(130, 70);
    		setResizable(false);
    		
    		setBounds((int)(getJAppletX()+getJAppletWidth()/2-65),(int)(getJAppletY()+getJAppletHeight()/2-35),130,70);
    	}

    	public String open() {
    	setVisible(true);
    	return result;
    	}
    	}
    	
}
